from flask import request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from sqlalchemy import desc
from app.models import Notice, AdminLog
from app.core.extensions import db
from . import admin_blueprint
from app.services.decorators import admin_required


@admin_blueprint.route('/notices', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_notices_list():
    """获取公告列表
    
    查询参数:
    - page: 页码，默认1
    - limit: 每页数量，默认10
    - title: 标题搜索
    - status: 状态筛选（0-禁用，1-启用）
    """
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 10, type=int)  # 使用limit替代per_page
    status = request.args.get('status', None, type=int)
    title = request.args.get('title', '')  # 添加标题搜索

    # 构建查询
    query = Notice.query

    # 根据状态筛选
    if status is not None:
        query = query.filter(Notice.status == status)

    # 根据标题搜索
    if title:
        query = query.filter(Notice.content.like(f'%{title}%'))

    # 执行分页查询
    pagination = query.order_by(Notice.sort.desc(), desc(Notice.id)).paginate(
        page=page, per_page=limit, error_out=False  # 使用limit替代per_page
    )

    notices = pagination.items

    # 构建响应数据
    result = {
        'code': 0,
        'message': '获取成功',
        'data': {
            'total': pagination.total,
            'pages': pagination.pages,
            'page': page,
            'per_page': limit,  # 使用limit替代per_page
            'items': [notice_to_dict(notice) for notice in notices],
            'list': [notice_to_dict(notice) for notice in notices]
        }
    }

    return jsonify(result)


@admin_blueprint.route('/notices', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def add_notice():
    """添加新公告"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    data = request.json

    # 提取表单数据
    title = data.get('title', '')  # 获取标题字段，默认为空字符串
    content = data.get('content')
    sort = data.get('sort', 0)
    status = data.get('status', 1)

    # 验证必要参数
    if not content:
        return jsonify({'code': 1, 'message': '通知内容不能为空'}), 400

    # 创建新通知
    # 标题字段存储在content字段中，这样处理前端传来的title
    if title:
        # 如果有标题，则使用标题
        final_content = title
    else:
        # 如果没有标题，则直接使用content
        final_content = content

    notice = Notice(
        content=final_content,  # 使用标题或内容作为内容
        sort=sort,
        status=status
    )

    db.session.add(notice)

    # 添加操作日志
    current_user = get_jwt_identity()

    log = AdminLog(
        admin_id=current_user,
        action='添加通知',
        ip=request.remote_addr,
        details=f'添加通知: {final_content[:30]}...'
    )
    db.session.add(log)

    db.session.commit()

    # 返回时，将content视为title传给前端
    notice_dict = notice_to_dict(notice)
    notice_dict['title'] = notice_dict['content']

    return jsonify({
        'code': 0,
        'message': '添加成功',
        'data': notice_dict
    })


@admin_blueprint.route('/notices/<int:notice_id>', methods=['GET', 'OPTIONS'])
@jwt_required(optional=True)
def get_notice_detail(notice_id):
    """获取公告详情"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    notice = Notice.query.get(notice_id)
    if not notice:
        return jsonify({'code': 1, 'message': '公告不存在'}), 404

    return jsonify({
        'code': 0,
        'message': '获取成功',
        'data': notice_to_dict(notice)
    })


@admin_blueprint.route('/notices/<int:notice_id>', methods=['PUT', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def update_notice(notice_id):
    """更新公告信息"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    notice = Notice.query.get(notice_id)
    if not notice:
        return jsonify({'code': 1, 'message': '公告不存在'}), 404
    data = request.json

    # 更新通知信息
    if 'content' in data:
        notice.content = data['content']
    if 'sort' in data:
        notice.sort = data['sort']
    if 'status' in data:
        notice.status = data['status']

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='编辑通知',
        ip=request.remote_addr,
        details=f'编辑通知 (ID: {notice.id})'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '更新成功',
        'data': notice_to_dict(notice)
    })


@admin_blueprint.route('/notices/<int:notice_id>', methods=['DELETE', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def delete_notice(notice_id):
    """删除公告"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    notice = Notice.query.get_or_404(notice_id)

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='删除通知',
        ip=request.remote_addr,
        details=f'删除通知 (ID: {notice.id})'
    )
    db.session.add(log)

    # 删除通知
    db.session.delete(notice)
    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '删除成功'
    })


@admin_blueprint.route('/notices/<int:notice_id>/publish', methods=['PUT', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def publish_notice(notice_id):
    """发布通知（更改状态为启用）"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    notice = Notice.query.get_or_404(notice_id)
    notice.status = 1

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='发布通知',
        ip=request.remote_addr,
        details=f'发布通知 (ID: {notice.id})'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '发布成功',
        'data': notice_to_dict(notice)
    })


@admin_blueprint.route('/notices/<int:notice_id>/withdraw', methods=['PUT', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def withdraw_notice(notice_id):
    """撤回通知（更改状态为禁用）"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    notice = Notice.query.get_or_404(notice_id)
    notice.status = 0

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='撤回通知',
        ip=request.remote_addr,
        details=f'撤回通知 (ID: {notice.id})'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '撤回成功',
        'data': notice_to_dict(notice)
    })


@admin_blueprint.route('/notices/sort', methods=['POST', 'OPTIONS'])
@jwt_required(optional=True)
@admin_required
def sort_notices():
    """批量更新通知排序"""
    # 处理OPTIONS请求
    if request.method == 'OPTIONS':
        return jsonify({'code': 0, 'message': 'OK'})

    data = request.json

    if not isinstance(data, list):
        return jsonify({'code': 1, 'message': '参数格式错误'}), 400

    for item in data:
        notice_id = item.get('id')
        sort = item.get('sort')

        if notice_id and sort is not None:
            notice = Notice.query.get(notice_id)
            if notice:
                notice.sort = sort

    # 添加操作日志
    log = AdminLog(
        admin_id=get_jwt_identity(),
        action='更新通知排序',
        ip=request.remote_addr,
        details='批量更新通知排序'
    )
    db.session.add(log)

    db.session.commit()

    return jsonify({
        'code': 0,
        'message': '更新成功'
    })


def notice_to_dict(notice):
    """将通知对象转换为字典"""
    return {
        'id': notice.id,
        'content': notice.content,
        'sort': notice.sort,
        'status': notice.status
    }
